use std::io;
use std::io::stdin;
use anyhow::Error;
use tokio::io::{AsyncBufReadExt, AsyncReadExt, AsyncWriteExt, BufReader, BufWriter, ReadBuf, ReadHalf, WriteHalf};
use tokio::net::TcpStream;
use tokio::sync;
use tokio::sync::mpsc::Sender;
use common::{Msg, MsgType};


const LOCAL_SERVER: &str = "127.0.0.1:8088";


async fn login(tx: Sender<Msg>) {
    // let (mut reader, mut writer) = tcp_stream.split();
    print!("请输入你的昵称:");

    let mut res = String::new();

    io::stdin().read_line(&mut res);
    res.trim().to_string();


    let msg_obj = Msg {
        msg_type: MsgType::SIGN_UP,
        data: res,
        nick_name: "UNKNOWN".to_string(),
    };


    tx.send(msg_obj);
}


#[tokio::main]
async fn main() -> anyhow::Result<(), Error> {


    let mut tcp_stream = TcpStream::connect(LOCAL_SERVER).await?;

    //  注意， 这里的channel 要用tokio的   ，不用std的
    let (tx, mut rx) = sync::mpsc::channel::<Msg>(16);

    let (tx2, mut rx2) = sync::mpsc::channel::<Msg>(16);


    // let tx_c = tx.clone();
    tokio::spawn(async move {
        let (reader, mut writer) = tcp_stream.split();

        let mut reader = BufReader::new(reader);

        let mut line = String::new();
        loop {
            tokio::select! {
                result = reader.read_line(&mut line) => {
                    if result.unwrap() == 0 {
                        break;
                    }

                    let msg_obj = Msg::parse(line.as_str());

                    line.clear();
                    match  msg_obj.msg_type {
                        MsgType::SIGN_UP_SUCCESS | MsgType::SIGN_UP_FAIL =>  {
                            tx2.send(msg_obj).await;
                        }

                        MsgType::SIGN_UP_BROADCAST =>  {
                            println!("用户{}  上线了",  msg_obj.nick_name)
                        }

                        MsgType::QUIT_BROADCAST => {

                             println!("用户{}  下线了",  msg_obj.nick_name)
                        }

                        _=>{


                            println!("用户【{}】:  {}",  msg_obj.nick_name , msg_obj.data)

                        }
                    }

                }

                result= rx.recv() => {

                    let msg_obj = result.unwrap();

                    let mut json = msg_obj.to_string() ;
                    // println!("client send msg is {}", json);
                    writer.write_all(json.as_bytes()).await.unwrap();
                }
            }
            ;
        }
    });


    loop {
        println!("请输入你的昵称:");

        let mut res = String::new();

        io::stdin().read_line(&mut res);
        res.trim().to_string();
        // res.replace("\n", "");

        let msg_obj = Msg::sign_up(res.as_str());

        tx.send(msg_obj).await;
        res.clear();

        let msg_res = rx2.recv().await.unwrap();
        match msg_res.msg_type {
            MsgType::SIGN_UP_SUCCESS => break,
            _ => {
                println!("{}", msg_res.data)

            }
        }
    }

    loop {
        let mut res = String::new();

        io::stdin().read_line(&mut res);
        res.trim().to_string();
        let mut res = res.replace("\n", "");


        // println!("res is {}", res.as_str());
        let mut msg_obj = match res.as_str() {
            ":quit" => Msg::quit(),
            _ => Msg::new(res.as_str()),
        };


        // println!("msg_obj is {:?}", msg_obj);
        tx.send(msg_obj).await;

        res.clear();
    }


    Ok(())
}